package main

import (
	"fmt"
	"time"
)

// 设备类型编码（CID1）
const CID1DistributedAC = 0x60  // 分散空调

// 命令信息编码（CID2）
const (
	CID2GetAnalogData    = 0x42  // 获取模拟量数据
	CID2GetInputStatus   = 0x43  // 获取开关输入状态
	CID2RemoteControl    = 0x45  // 遥控开关机
	CID2GetSystemParams  = 0x47  // 获取系统参数
	CID2SetSystemParams  = 0x49  // 设定系统参数
	CID2GetModuleTime    = 0x4D  // 获取监测模块时间
	CID2SetModuleTime    = 0x4E  // 设定监测模块时间
	CID2GetProtocolVer   = 0x4F  // 获取通信协议版本号
	CID2GetDeviceAddress = 0x50  // 获取设备地址
	CID2GetManufacturer  = 0x51  // 获取厂家信息
	CID2GetUnitStatus    = 0x82  // 获取机组状态
	CID2GetUnitMode      = 0x85  // 获取机组运行模式和报警状态
	CID2GetAnalogOutput  = 0x86  // 获取模拟量输出
)

// 整型数（2字节，支持有符号和无符号）
func encodeInteger(value int16) []byte {
	// 先高字节后低字节（大端模式）
	return []byte{byte(value >> 8), byte(value & 0xFF)}
}

// 无符号字符型数（1字节）
func encodeChar(value byte) []byte {
	return []byte{value}
}

// 日期时间格式（年-月-日-时-分-秒）
func encodeDateTime(t time.Time) []byte {
	year := uint16(t.Year())
	// 年使用无符号2字节（高字节在前）
	yearBytes := []byte{byte(year >> 8), byte(year & 0xFF)}
	// 月、日、时、分、秒使用字符型1字节
	month := byte(t.Month())
	day := byte(t.Day())
	hour := byte(t.Hour())
	minute := byte(t.Minute())
	second := byte(t.Second())

	// 返回拼接后的字节
	return append(yearBytes, append([]byte{month, day, hour, minute, second}...)...)
}

// 构建协议帧
func buildProtocolFrame(cid1 byte, cid2 byte, info []byte) []byte {
	// 构建SOI（起始符）、VER、ADR（地址），CID1、CID2、LENGTH、INFO、CHKSUM、EOI
	soi := []byte{0x7E}  // SOI
	ver := []byte{0x21}   // VER
	adr := []byte{0x01}   // ADR，默认为1
	length := encodeInteger(int16(len(info)))  // LENGTH
	checksum := calculateChecksum(append(soi, append(ver, append(adr, append([]byte{cid1, cid2}, append(length, info...)...)...)...)...)...) // CHKSUM
	eoi := []byte{0x0D} // EOI（结束符）

	// 拼接整个协议帧
	frame := append(soi, append(ver, append(adr, append([]byte{cid1, cid2}, append(length, append(info, append(checksum, eoi...)...)...)...)...)...)...)
	return frame
}

// 计算校验和（CHKSUM）
func calculateChecksum(data []byte) []byte {
	var sum int32
	for _, b := range data {
		sum += int32(b)
	}
	checksum := sum % 65536
	checksum = ^checksum + 1
	return []byte{byte(checksum >> 8), byte(checksum & 0xFF)}
}

func main() {
	// 示例：构建协议帧，获取模拟量数据命令
	cid1 := CID1DistributedAC   // 分散空调设备
	cid2 := CID2GetAnalogData   // 获取模拟量数据
	info := encodeInteger(12345) // 示例数据

	// 构建协议帧
	protocolFrame := buildProtocolFrame(cid1, cid2, info)

	// 输出协议帧（以十六进制格式打印）
	fmt.Printf("协议帧: %X\n", protocolFrame)
}
